package http.mapping;

import http.annotation.NettyMapping;
import http.util.PackageUtil;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMethod;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HandlerMapper {
    private static Map<String, HandlerMethod> handlerMaps = new ConcurrentHashMap<>();

    static {
        List<String> classNames = PackageUtil.getClassName("http.controller");
        for (String className : classNames) {
            try {
                Class<?> clazz = Class.forName(className);
                NettyMapping nettyMapping = clazz.getAnnotation(NettyMapping.class);
                if (nettyMapping == null) {
                    continue;
                }
                Object handeler = clazz.newInstance();
                String classMapper = nettyMapping.value()[0];
                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    NettyMapping methodMapping = method.getAnnotation(NettyMapping.class);
                    if (methodMapping == null) {
                        continue;
                    }
                    String url = "";
                    if (!classMapper.endsWith("/") && !methodMapping.value()[0].endsWith("/")) {
                        url = classMapper + "/" + methodMapping.value()[0];
                    } else {
                        url = classMapper + methodMapping.value()[0];
                    }
                    url = url.replace("//", "/");
                    System.out.println("url:" + url);
                    handlerMaps.put(url, new HandlerMethod(handeler, method));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }


    public static HandlerMethod getHandler(FullHttpRequest req) {
        String uri = getMapperKey(req.uri());
        HandlerMethod handlerMethod = handlerMaps.get(uri);
        if (handlerMethod == null) {
            System.out.println("没有与：" + uri + "，匹配的handler");
            return null;
        }
        NettyMapping nettyMapping = handlerMethod.getMethod().getAnnotation(NettyMapping.class);
        RequestMethod[] methods = nettyMapping.method();
        if(http.util.ArrayUtil.isNotEmpty(methods)){
            boolean isMethodMatch=false;
            HttpMethod httpMethod = req.method();

            for (RequestMethod method : methods) {
                if(method.name().equals(httpMethod.name())){
                    isMethodMatch=true;
                    break;
                }
            }
            if(!isMethodMatch){
                System.out.println("没有与：" + uri + "，匹配的handler");
                return null;
            }
        }
        handlerMethod.setReq(req);
        return handlerMethod;
    }

    private static String getMapperKey(String uri) {
        String result = uri;
        int indexOf = uri.indexOf("?");
        if (indexOf != -1) {
            result = uri.substring(0, indexOf);
        }
        if (result.endsWith("/") && result.length() > 1) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }


}
